package cn.ywyself.extend.render;

import cn.ywyself.extend.utils.ExcelUtils;
import com.jfinal.core.JFinal;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.List;

/**
 * 提供Excel文档下载
 *
 * @author : ywyself
 * @created : 2018-10-12 17:04
 */
public class YsExcelRender extends Render {
    protected static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";

    private ExcelUtils excel;
    private String fileName = "ceshi.xls";

    public YsExcelRender(List<List<Object>> data) {
        excel = ExcelUtils.init();
        excel.createSheet();
        for (List<Object> row : data) {
            excel.createRow();
            for (Object cell : row) {
                excel.addCell(String.valueOf(cell));
            }
        }
    }

    /**
     * Render to client
     */
    @Override
    public void render() {
        // ---------
        response.setHeader("Accept-Ranges", "bytes");
//        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-disposition", "attachment; " + encodeFileName(request, fileName));
        String contentType = JFinal.me().getServletContext().getMimeType(fileName);
        response.setContentType(contentType != null ? contentType : DEFAULT_CONTENT_TYPE);

        OutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            excel.write(outputStream);
            outputStream.flush();
        } catch (IOException e) {    // ClientAbortException、EofException 直接或间接继承自 IOException
            String name = e.getClass().getSimpleName();
            if (name.equals("ClientAbortException") || name.equals("EofException")) {

            } else {
                throw new RenderException(e);
            }
        } catch (Exception e) {
            throw new RenderException(e);
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 依据浏览器判断编码规则
     */
    public String encodeFileName(HttpServletRequest request, String fileName) {
        String userAgent = request.getHeader("User-Agent");
        try {
            String encodedFileName = URLEncoder.encode(fileName, "UTF8");
            // 如果没有UA，则默认使用IE的方式进行编码
            if (userAgent == null) {
                return "filename=\"" + encodedFileName + "\"";
            }

            userAgent = userAgent.toLowerCase();
            // IE浏览器，只能采用URLEncoder编码
            if (userAgent.indexOf("msie") != -1) {
                return "filename=\"" + encodedFileName + "\"";
            }

            // Opera浏览器只能采用filename*
            if (userAgent.indexOf("opera") != -1) {
                return "filename*=UTF-8''" + encodedFileName;
            }

            // Safari浏览器，只能采用ISO编码的中文输出,Chrome浏览器，只能采用MimeUtility编码或ISO编码的中文输出
            if (userAgent.indexOf("safari") != -1 || userAgent.indexOf("applewebkit") != -1 || userAgent.indexOf("chrome") != -1) {
                return "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\"";
            }

            // FireFox浏览器，可以使用MimeUtility或filename*或ISO编码的中文输出
            if (userAgent.indexOf("mozilla") != -1) {
                return "filename*=UTF-8''" + encodedFileName;
            }

            return "filename=\"" + encodedFileName + "\"";
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
}
